﻿using AutoMapper;
using wwl.Contract.Dtos.Common;

namespace wwl.Application.Mappings
{
  /// <summary>
  /// AutoMapper 泛型分页结果转换器（应用层）
  /// 负责将领域层分页结果 <see cref="PagedResult{TSource}"/> 转换为契约层分页结果 <see cref="PagedResult{TDestination}"/>
  /// 适配所有实体的分页数据转换场景，自动处理列表项的映射与分页元数据的复制
  /// </summary>
  /// <typeparam name="TSource">源类型（通常为领域实体，如 <see cref="wwl.Domain.Entities.Rbac.Tenant"/>）</typeparam>
  /// <typeparam name="TDestination">目标类型（通常为DTO，如 <see cref="Contract.Dtos.Responses.Rbac.TenantResponse"/>）</typeparam>
  public class PagedResultConverter<TSource, TDestination> : ITypeConverter<PagedResult<TSource>, PagedResult<TDestination>>
  {
    /// <summary>
    /// 执行分页结果的转换逻辑
    /// </summary>
    /// <param name="source">源分页结果（包含领域实体列表及分页元数据）</param>
    /// <param name="destination">目标分页结果（初始可能为null，由转换器负责实例化）</param>
    /// <param name="context">AutoMapper 解析上下文，提供类型映射的环境信息（如子对象映射器）</param>
    /// <returns>转换后的目标分页结果（包含DTO列表及复制的分页元数据）</returns>
    /// <remarks>
    /// 转换流程：
    /// 1. 映射列表数据：通过 AutoMapper 上下文将源列表（<see cref="PagedResult{TSource}.Items"/>）
    ///    转换为目标列表（<see cref="List{TDestination}"/>），依赖已配置的 <typeparamref name="TSource"/>→<typeparamref name="TDestination"/> 映射规则。
    /// 2. 复制分页元数据：将源分页结果中的分页参数（总条数、页码、页大小）直接复制到目标对象，
    ///    确保分页信息在转换过程中不丢失，支撑前端分页组件的正确渲染。
    /// 3. 实例化目标对象：若目标对象为null，自动创建新实例，避免空引用异常。
    /// </remarks>
    public PagedResult<TDestination> Convert(PagedResult<TSource> source, PagedResult<TDestination> destination, ResolutionContext context)
    {
      // 将源分页结果中的领域实体列表转换为DTO列表
      // 依赖 AutoMapper 已配置的 TSource→TDestination 映射（如 Tenant→TenantDto）
      var items = context.Mapper.Map<List<TDestination>>(source.Items);

      // 实例化目标分页结果并赋值：包含转换后的DTO列表和复制的分页元数据
      return new PagedResult<TDestination>
      {
        Items = items,               // 转换后的DTO列表
        TotalCount = source.TotalCount, // 总条数（直接复制源数据）
        PageIndex = source.PageIndex,   // 当前页码（直接复制源数据）
        PageSize = source.PageSize      // 每页条数（直接复制源数据）
      };
    }
  }
}